using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Linq;
using BSDS.Core.Model.Data;
using BSDS.Core.Model.Conversion;

namespace BSDS.Core.Data.Local.Xml.Parsing
{
    public class XmlFormatParser : IParser
    {
        private readonly XmlEntityParser entityParser;
        private readonly XmlAttributeParser attributeParser;

        public XmlFormatParser()
        {
            entityParser = new XmlEntityParser();
            attributeParser = new XmlAttributeParser();
        }

        public BsdsData Parse(XDocument document, string filename, string xsns = "http://www.w3.org/2001/XMLSchema")
        {
            var schemaQuery = document.Descendants(XName.Get("schema", xsns));
            if (schemaQuery.Count() == 0)
            {
                throw new ArgumentException("No schema found in file: " + filename);
            }

            var entityNameQuery = document.Descendants(XName.Get("element", xsns)).Skip(1).FirstOrDefault();
            if (entityNameQuery == null || entityNameQuery.Attribute("name") == null)
            {
                throw new ArgumentException("Invalid file format. Problem extracting entity name.");
            }

            var schemaNode = schemaQuery.First();
            var entityName = entityNameQuery.Attribute("name").Value;

            var attributeInfos = attributeParser.FromXml(schemaNode, xsns);

            var entities = new List<EntityValue>();
            var childNodes = document.Descendants(XName.Get(entityName));

            foreach (var childNode in childNodes)
            {
                entities.Add(entityParser.FromXml(attributeInfos, childNode));
            }

            return new BsdsData(entities.ToArray(), filename, DataFormat.Xml, entityName); 
        }

        public BsdsData Parse(string filename, FormatConvertMode convertMode)
        {
            var document = XDocument.Load(filename);

            var data = Parse(document, filename);

            return data;
        }

        public BsdsData Parse(XDocument document)
        {
            var data = Parse(document, string.Empty, "http://www.w3.org/2001/XMLSchema");

            return data;
        }
    }
}